import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Properties;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.springframework.util.FileCopyUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


/**
 * 安装jar
 * @author ls
 *
 */
public abstract class BaseMvn {
	
	private static final String PARENT = "parent";
	private static final String VERSION = "version";
	private static final String GROUP_ID = "groupId";
	private static final String ARTIFACT_ID = "artifactId";
	private static final String PACKAGING = "packaging";
	
	private final String jarPath;
	
	public BaseMvn(String jafPath) {
		super();
		this.jarPath = jafPath;
	}

	
	/**
	 * 执行命令
	 * @throws IOException
	 */
	public void exe( ) throws IOException{
		File f = new File(jarPath);
		if(f.isDirectory()){
			File[] strs = f.listFiles();
			for (File name : strs) {
				if(name.isFile()){
					if(name.getName().endsWith(".pom")){
						System.out.println();
						System.out.println("pomName:"+name.getAbsolutePath());
					    exe(getPOMFile(name.getAbsolutePath()));
					}else{
						installOne(name.getAbsolutePath());
					}
				}
			}
		}else{
			installOne(jarPath);
		}
	}
	
	private POM getPOMFile(String path){
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();  
		POM p = new POM(); 
		p.setJarName(path);
		p.setPomFile(path);
		try  
        {  
            DocumentBuilder db = dbf.newDocumentBuilder();  
            Document doc = db.parse(path);  
            NodeList dogList = doc.getElementsByTagName("project"); 
    		Node dog = dogList.item(0);  
            setValue(p, dog, false);
        }  
        catch (Exception e)  
        {  
            e.printStackTrace();  
        }  
        return p;
	}
	
	private void setValue(POM p,Node dog,boolean isParent){
        int index = 4;
        for (Node node = dog.getFirstChild(); node != null; node = node.getNextSibling())  
        {  
            if (node.getNodeType() == Node.ELEMENT_NODE)  
            {  
                String name = node.getNodeName();  
                if(PARENT.equals(name)){
                	setValue(p, node, true);
                	continue;
                }
                String value = node.getFirstChild().getNodeValue();  
                if(VERSION.equalsIgnoreCase(name)){
                	if(isBlank(value)){
                		p.setVersion(value);
                	}else if(!isBlank(value) && !isParent){
                		p.setVersion(value);
                	}
                	index--;
                }else  if(GROUP_ID.equalsIgnoreCase(name)){
                	if(isBlank(value)){
                		p.setGroupId(value);
                	}else if(!isBlank(value) && !isParent){
                		p.setGroupId(value);
                	}
                	index--;
                }else  if(ARTIFACT_ID.equalsIgnoreCase(name)){
                	if(isBlank(value)){
                		p.setArtifactId(value);
                	}else if(!isBlank(value) && !isParent){
                		p.setArtifactId(value);
                	}
                	index--;
                }else  if(PACKAGING.equalsIgnoreCase(name)){
                	if(isBlank(value)){
                		p.setPackaging(value);
                	}else if(!isBlank(value) && !isParent){
                		p.setPackaging(value);
                	}
                	index--;
                }
                if(index<=0){
                	break;
                }
            }  
        }  
	}
	
	private void installOne(String jarName) throws IOException{
		System.out.println();
		System.out.println("jarName:"+jarName);
	    exe(getPOM(jarName));
	}
	
	protected boolean isBlank(String str){
		return !(str==null || "".equals(str));
	} 
	
	/**
	 * 需用执行的命令
	 * @param pom
	 */
	public abstract void exe(POM pom);
	
	private POM getPOM(String jarName) throws IOException{
		JarFile jarFile = new JarFile(jarName);
		Enumeration<?> enum1 = jarFile.entries();
		JarEntry entry = null;
		JarEntry pomEntry = null;
		int need = 2;
		while (enum1.hasMoreElements()) {
			JarEntry entry1 = (JarEntry) enum1.nextElement();
			if(entry1.getName().endsWith("pom.properties")){
				entry = entry1;
				need--;
			}
			if(entry1.getName().endsWith("pom.xml")){
				pomEntry = entry1;
				need--;
			}
			if(need<=0){
				break;
			}
		}
		
		POM pom = new POM();
		
		InputStream input = jarFile.getInputStream(entry);
		Properties p = new Properties();
		p.load(input);
		pom.setJarName(jarName);
		Enumeration<?> enu2 = p.propertyNames();
		int needPro = 3;
		while(enu2.hasMoreElements()){
		    String key = (String)enu2.nextElement();
		    if(VERSION.equalsIgnoreCase(key)){
		    	pom.setVersion(p.getProperty(key));
		    	needPro--;
		    }else  if(GROUP_ID.equalsIgnoreCase(key)){
		    	pom.setGroupId(p.getProperty(key));
		    	needPro--;
		    }else  if(ARTIFACT_ID.equalsIgnoreCase(key)){
		    	pom.setArtifactId(p.getProperty(key));
		    	needPro--;
		    }
			if(needPro<=0){
				break;
			} 
		}
		String name = new File(jarName).getName();
		int index = name.lastIndexOf(".");
		pom.setPackaging(name.substring(index+1));
		//pom文件
		InputStream input1 = jarFile.getInputStream(pomEntry);
		File jar = new File(jarName);
		String parentStr = jar.getParent()+File.separator+"pom"+File.separator;
		File parent = new File(parentStr);
		if(!parent.exists()){
			parent.mkdirs();
		}
		String pomPath = parentStr + name.substring(0, index)+".pom";
		FileCopyUtils.copy(input1, new FileOutputStream(pomPath));
		pom.setPomFile(pomPath);
		
		String src = jar.getParent()+File.separator + name.substring(0, index)+"-sources"+".jar";
		File srcFile = new File(src);
		if(srcFile.exists()){
			pom.setSrcFile(srcFile.getAbsolutePath());
		}
		String doc = jar.getParent()+File.separator + name.substring(0, index)+"-javadoc"+".jar";
		File docFile = new File(doc);
		if(docFile.exists()){
			pom.setJavadoc(docFile.getAbsolutePath());
		}
		jarFile.close();
		return pom;
	}
	
	protected String getCommonOrder(POM pom){
		StringBuilder sb = new StringBuilder();
		sb.append(" -Dfile="+new File(pom.getJarName()).getAbsolutePath());
		sb.append(" -DgroupId="+pom.getGroupId());
		sb.append(" -DartifactId="+pom.getArtifactId());
		sb.append(" -Dversion="+pom.getVersion());
		sb.append(" -Dpackaging="+pom.getPackaging());
		if(!(pom.getPomFile()==null || "".equals(pom.getPomFile()))){
			sb.append(" -DpomFile="+pom.getPomFile());
		}
		if(!(pom.getSrcFile()==null || "".equals(pom.getSrcFile()))){
			sb.append(" -Dsources="+pom.getSrcFile());
		}
		if(!(pom.getJavadoc()==null || "".equals(pom.getJavadoc()))){
			sb.append(" -Djavadoc="+pom.getJavadoc());
		}
		return sb.toString();
	}
	
	public class POM{
		private String jarName;
		private String version;
		private String groupId;
		private String artifactId;
		private String packaging = "jar";
		private String pomFile;
		private String srcFile;
		private String javadoc;
		public String getVersion() {
			return version;
		}
		public void setVersion(String version) {
			this.version = version;
		}
		public String getGroupId() {
			return groupId;
		}
		public void setGroupId(String groupId) {
			this.groupId = groupId;
		}
		public String getArtifactId() {
			return artifactId;
		}
		public void setArtifactId(String artifactId) {
			this.artifactId = artifactId;
		}
		@Override
		public String toString() {
			return "POM [jarName=" + jarName + ", version=" + version + ", groupId=" + groupId + ", artifactId="
					+ artifactId + ", packaging=" + packaging + ", pomFile=" + pomFile + ", srcFile=" + srcFile
					+ ", javadoc=" + javadoc + "]";
		}
		public String getJarName() {
			return jarName;
		}
		public void setJarName(String jarName) {
			this.jarName = jarName;
		}
		public String getPackaging() {
			return packaging;
		}
		public void setPackaging(String packaging) {
			this.packaging = packaging;
		}
		public String getPomFile() {
			return pomFile;
		}
		public void setPomFile(String pomFile) {
			this.pomFile = pomFile;
		}
		public String getSrcFile() {
			return srcFile;
		}
		public void setSrcFile(String srcFile) {
			this.srcFile = srcFile;
		}
		public String getJavadoc() {
			return javadoc;
		}
		public void setJavadoc(String javadoc) {
			this.javadoc = javadoc;
		}
	}
}
